﻿using System;
using System.IO;
using System.Xml;
using System.Data;
using System.Data.Common;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections;
using System.Collections.Specialized;

namespace PickGold
{
	/// <summary>
	/// CDataToExcel 的摘要说明
	/// </summary>
	public class CDataToExcel : IDisposable
	{
		protected Stream _OutStream = null;
		protected HDataProcessor[] _Processor = null;
		protected NameValueCollection _NamedColumnTitle = null;
		protected string[] _ColumnName = null;
		protected string[] _ColumnTitle = null;
		protected string _FileName = null;
		protected string _DocumentTitle = null;
		protected IDataReader _DataReader = null;
		protected DataTable _DataTable = null;
		protected DataView _DataView = null;
		private bool _Disposed = false;

		/// <summary>
		/// 构造当前类型的一个实例
		/// </summary>
		protected CDataToExcel()
		{
			//ToDo:none;
		}

		/// <summary>
		/// 构造当前类型的一个实例
		/// </summary>
		/// <param name="outStream">输出流</param>
		public CDataToExcel(Stream outStream)
		{
			this._OutStream = outStream;
		}

		/// <summary>
		/// 析构
		/// </summary>
		~CDataToExcel()
		{
			try
			{
				this.Dispose(false);
			}
			catch (Exception x)
			{
				Tracker.WriteError(x);
				Common.WriteEvent(x);
			}
		}

		/// <summary>
		/// 数据处理器，按列顺序，没有或不需要则为空
		/// </summary>
		public HDataProcessor[] Processor
		{
			set
			{
				this._Processor = value;
			}
			get
			{
				return this._Processor;
			}
		}

		/// <summary>
		/// 列标题集合
		/// </summary>
		public NameValueCollection NamedColumnTitle
		{
			set
			{
				this._NamedColumnTitle = value;
			}
			get
			{
				if (this._NamedColumnTitle == null)
					this._NamedColumnTitle = new NameValueCollection();
				return this._NamedColumnTitle;
			}
		}

		/// <summary>
		/// 列名
		/// </summary>
		public string[] ColumnName
		{
			set
			{
				this._ColumnName = value;
			}
			get
			{
				return this._ColumnName;
			}
		}

		/// <summary>
		/// 列标题，按列顺序，没有或不需要则为空
		/// </summary>
		public string[] ColumnTitle
		{
			set
			{
				this._ColumnTitle = value;
			}
			get
			{
				return this._ColumnTitle;
			}
		}

		/// <summary>
		/// 输入文件名
		/// </summary>
		public string FileName
		{
			set
			{
				this._FileName = value;
			}
			get
			{
				return this._FileName;
			}
		}

		/// <summary>
		/// 输出文档名，在数据上方显示
		/// </summary>
		public string DocumentTitle
		{
			set
			{
				this._DocumentTitle = value;
			}
			get
			{
				return this._DocumentTitle;
			}
		}

		/// <summary>
		/// 输出公司，在文件属性中
		/// </summary>
		/// <returns></returns>
		protected virtual string GetCompany()
		{
			return "HongShijin";
		}

		/// <summary>
		/// 导出数据
		/// </summary>
		/// <param name="dr">要导出数据的数据读取器</param>
		/// <returns>文件名，非空则成功</returns>
		public string Export(IDataReader dr)
		{
			if (dr is DbDataReader && !((DbDataReader)dr).HasRows)
				return null;

			if (dr == null || dr.IsClosed || dr.FieldCount == 0)
				return null;

			this._DataReader = dr;
			this._DataTable = null;
			this._DataView = null;

			if ((this._ColumnTitle == null || this._ColumnTitle.Length == 0) && this._ColumnName != null && this._ColumnName.Length > 0)
			{
				this._ColumnTitle = new string[this._ColumnName.Length];

				for (int i = 0; i < this._ColumnTitle.Length; i++)
					this._ColumnTitle[i] = this._ColumnName[i];
			}
			else if ((this._ColumnName == null || this._ColumnName.Length == 0) && this._ColumnTitle != null && this._ColumnTitle.Length > 0)
			{
				if (this._ColumnTitle.Length > dr.FieldCount)
					this._ColumnName = new string[dr.FieldCount];
				else
					this._ColumnName = new string[this._ColumnTitle.Length];

				for (int i = 0; i < this._ColumnName.Length; i++)
					this._ColumnName[i] = dr.GetName(i);
			}

			if (this._ColumnName != null && this._ColumnName.Length > 0
				&& this._ColumnTitle != null && this._ColumnTitle.Length > 0
				&& dr != null && !dr.IsClosed)
			{
				for (int i = 0; i < this._ColumnName.Length && i < this._ColumnTitle.Length && i < dr.FieldCount; i++)
					this.NamedColumnTitle.Set(this._ColumnName[i], this._ColumnTitle[i]);
			}

			return this.ExportToStream();
		}

		/// <summary>
		/// 导出数据
		/// </summary>
		/// <param name="dt">要导出数据的数据表</param>
		/// <returns>文件名，非空则成功</returns>
		public string Export(DataTable dt)
		{
			if (dt == null || dt.Columns.Count == 0 || dt.Rows.Count == 0)
				return null;

			this._DataReader = null;
			this._DataTable = dt;
			this._DataView = null;

			if ((this._ColumnTitle == null || this._ColumnTitle.Length == 0) && this._ColumnName != null && this._ColumnName.Length > 0)
			{
				this._ColumnTitle = new string[this._ColumnName.Length];

				for (int i = 0; i < this._ColumnTitle.Length; i++)
					this._ColumnTitle[i] = this._ColumnName[i];
			}
			else if ((this._ColumnName == null || this._ColumnName.Length == 0) && this._ColumnTitle != null && this._ColumnTitle.Length > 0)
			{
				if (this._ColumnTitle.Length > dt.Columns.Count)
					this._ColumnName = new string[dt.Columns.Count];
				else
					this._ColumnName = new string[this._ColumnTitle.Length];

				for (int i = 0; i < this._ColumnName.Length; i++)
					this._ColumnName[i] = dt.Columns[i].ColumnName;
			}

			if (this._ColumnName != null && this._ColumnName.Length > 0
				&& this._ColumnTitle != null && this._ColumnTitle.Length > 0
				&& dt != null && dt.Columns.Count > 0)
			{
				for (int i = 0; i < this._ColumnName.Length && i < this._ColumnTitle.Length && i < dt.Columns.Count; i++)
					this.NamedColumnTitle.Set(this._ColumnName[i], this._ColumnTitle[i]);
			}

			return this.ExportToStream();
		}

		/// <summary>
		/// 导出数据
		/// </summary>
		/// <param name="dv">要导出数据的数据视图</param>
		/// <returns>文件名，非空则成功</returns>
		public string Export(DataView dv)
		{
			if (dv == null || dv.Table.Columns.Count == 0 || dv.Count == 0)
				return null;

			this._DataReader = null;
			this._DataTable = null;
			this._DataView = dv;

			if ((this._ColumnTitle == null || this._ColumnTitle.Length == 0) && this._ColumnName != null && this._ColumnName.Length > 0)
			{
				this._ColumnTitle = new string[this._ColumnName.Length];

				for (int i = 0; i < this._ColumnTitle.Length; i++)
					this._ColumnTitle[i] = this._ColumnName[i];
			}
			else if ((this._ColumnName == null || this._ColumnName.Length == 0) && this._ColumnTitle != null && this._ColumnTitle.Length > 0)
			{
				if (this._ColumnTitle.Length > dv.Table.Columns.Count)
					this._ColumnName = new string[dv.Table.Columns.Count];
				else
					this._ColumnName = new string[this._ColumnTitle.Length];

				for (int i = 0; i < this._ColumnName.Length; i++)
					this._ColumnName[i] = dv.Table.Columns[i].ColumnName;
			}

			if (this._ColumnName != null && this._ColumnName.Length > 0
				&& this._ColumnTitle != null && this._ColumnTitle.Length > 0
				&& dv != null && dv.Table.Columns.Count > 0)
			{
				for (int i = 0; i < this._ColumnName.Length && i < this._ColumnTitle.Length && i < dv.Table.Columns.Count; i++)
					this.NamedColumnTitle.Set(this._ColumnName[i], this._ColumnTitle[i]);
			}

			return this.ExportToStream();
		}

		/// <summary>
		/// 是否能继续输出
		/// </summary>
		/// <returns>是否能继续</returns>
		protected virtual bool CanContinue()
		{
			return this._OutStream.CanWrite;
		}

		/// <summary>
		/// 是否有数据
		/// </summary>
		/// <param name="currentIndex">列索引</param>
		/// <returns>是否有数据</returns>
		protected bool HasData(int currentIndex)
		{
			if (this._DataReader != null)
				return this._DataReader.Read();

			if (this._DataTable != null)
				return this._DataTable.Rows.Count > currentIndex;

			if (this._DataView != null)
				return this._DataView.Count > currentIndex;

			return false;
		}

		/// <summary>
		/// 取指定行列的数据
		/// </summary>
		/// <param name="rowIndex">行索引</param>
		/// <param name="fieldIndex">列索引</param>
		/// <returns>指定行列的数据</returns>
		protected object GetData(int rowIndex, int fieldIndex)
		{
			string t = this.NamedColumnTitle.GetKey(fieldIndex);

			if (t.IndexOf('\0') >= 0)
				t = t.Remove(t.IndexOf('\0'));
			else if (t.IndexOf('\t') >= 0)
				t = t.Remove(t.IndexOf('\t'));
			else if (t.IndexOf('\r') >= 0)
				t = t.Remove(t.IndexOf('\r'));
			else if (t.IndexOf('\n') >= 0)
				t = t.Remove(t.IndexOf('\n'));

			try
			{
				if (this._DataReader != null)
					return this._DataReader[t];

				if (this._DataTable != null)
					return this._DataTable.Rows[rowIndex - 1][t];

				if (this._DataView != null)
					return this._DataView[rowIndex - 1][t];
			}
			catch (Exception x)
			{
				Tracker.WriteError(x);
				return "数据库源错误：" + x.Message;
			}

			return null;
		}

		/// <summary>
		/// 将任意数据转换成符合CXCEL文件格式的字符
		/// </summary>
		/// <param name="rowIndex">行索引</param>
		/// <param name="fieldIndex">列索引</param>
		/// <returns>转换后数据</returns>
		protected string DataToString(int rowIndex, int fieldIndex)
		{
			string t;
			object o = this.GetData(rowIndex, fieldIndex);
			if (o == null)
				return string.Empty;

			if (this._Processor == null || this._Processor.Length <= fieldIndex || this._Processor[fieldIndex] == null)
			{
				t = o.ToString();
				if (string.IsNullOrEmpty(t))
					return t;

				return Regex.Replace(t, @"[\x00-\x20]", string.Empty, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Multiline);
			}

			try
			{
				t = this._Processor[fieldIndex](o).ToString();
				if (string.IsNullOrEmpty(t))
					return t;

				return Regex.Replace(t, @"[\x00-\x20]", string.Empty, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Multiline);
			}
			catch (Exception x)
			{
				Tracker.WriteError(x);
				return "数据处理错误：" + x.Message;
				//return o.ToString().Replace('\0', ' ');
			}
		}

		/// <summary>
		/// 导出到流
		/// </summary>
		/// <returns>文件名，非空则成功</returns>
		protected virtual string ExportToStream()
		{
			const long SHEET_MAX_ROW = 65530;

			const string URI_WORKBOOK = "urn:schemas-microsoft-com:office:spreadsheet";
			const string URI_DOCUMENT_PROPERTIES = "urn:schemas-microsoft-com:office:office";
			const string URI_EXCEL_WORKBOOK = "urn:schemas-microsoft-com:office:excel";
			const string URI_WORKSHEET_OPTIONS = "urn:schemas-microsoft-com:office:excel";

			const string NS_O = "o";
			const string NS_X = "x";
			const string NS_SS = "ss";
			const string NS_HTML = "html";

			const string URI_O = "urn:schemas-microsoft-com:office:office";
			const string URI_X = "urn:schemas-microsoft-com:office:excel";
			const string URI_SS = "urn:schemas-microsoft-com:office:spreadsheet";
			const string URI_HTML = "http://www.w3.org/TR/REC-html40";

			int i;
			object o;

			int iRowCount = 0;
			int iSheetCount = 0;

			if (this._DataReader != null)
			{
				if (this._DataReader is DbDataReader && !((DbDataReader)this._DataReader).HasRows)
					return null;

				if (this._DataReader.IsClosed || !this._DataReader.Read())
					return null;

				if (this.NamedColumnTitle.Count == 0)
				{
					for (i = 0; i < this._DataReader.FieldCount; i++)
						this.NamedColumnTitle.Set(this._DataReader.GetName(i), this._DataReader.GetName(i));
				}
			}
			else if (this._DataTable != null)
			{
				if (this._DataTable.Rows.Count == 0)
					return null;

				if (this.NamedColumnTitle.Count == 0)
				{
					for (i = 0; i < this._DataTable.Columns.Count; i++)
						this.NamedColumnTitle.Set(this._DataTable.Columns[i].ColumnName, this._DataTable.Columns[i].ColumnName);
				}
			}
			else if (this._DataView != null)
			{
				if (this._DataView.Count == 0)
					return null;

				if (this.NamedColumnTitle.Count == 0)
				{
					for (i = 0; i < this._DataView.Table.Columns.Count; i++)
						this.NamedColumnTitle.Set(this._DataView.Table.Columns[i].ColumnName, this._DataView.Table.Columns[i].ColumnName);
				}
			}
			else
			{
				throw new Exception("不可接受的对象类型，对象必须为 [DbDataReader] [DataTable] [DataView] 中的一种！");
				//return null;
			}

			XmlWriterSettings xws = new XmlWriterSettings();
			xws.CloseOutput = true;
			xws.Indent = true;
			xws.IndentChars = "\t";
			xws.NewLineChars = "\r\n";
			XmlWriter xw = XmlWriter.Create(this._OutStream, xws);
			xw.WriteStartDocument();
			xw.WriteProcessingInstruction("mso-application", "progid=\"Excel.Sheet\"");
			//xw.WriteString("<?mso-application progid=\"Excel.Sheet\"?>");
			xw.WriteStartElement("Workbook", URI_WORKBOOK);
			xw.WriteAttributeString("xmlns", NS_O, null, URI_O);
			xw.WriteAttributeString("xmlns", NS_X, null, URI_X);
			xw.WriteAttributeString("xmlns", NS_SS, null, URI_SS);
			xw.WriteAttributeString("xmlns", NS_HTML, null, URI_HTML);

			xw.WriteStartElement("", "DocumentProperties", URI_DOCUMENT_PROPERTIES);

			xw.WriteStartElement("", "Author", URI_DOCUMENT_PROPERTIES);
			xw.WriteString("HongShijin");
			xw.WriteEndElement();//Author

			xw.WriteStartElement("", "LastAuthor", URI_DOCUMENT_PROPERTIES);
			xw.WriteString("HongShijin");
			xw.WriteEndElement();//LastAuthor

			xw.WriteStartElement("", "Created", URI_DOCUMENT_PROPERTIES);
			xw.WriteString(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
			xw.WriteEndElement();//Created

			xw.WriteStartElement("", "LastSaved", URI_DOCUMENT_PROPERTIES);
			xw.WriteString(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
			xw.WriteEndElement();//LastSaved

			xw.WriteStartElement("", "Company", URI_DOCUMENT_PROPERTIES);
			xw.WriteString(this.GetCompany());
			xw.WriteEndElement();//Company

			xw.WriteStartElement("", "Version", URI_DOCUMENT_PROPERTIES);
			xw.WriteString("11.6568");
			xw.WriteEndElement();//Version

			xw.WriteEndElement();//DocumentProperties

			xw.WriteStartElement("", "ExcelWorkbook", URI_EXCEL_WORKBOOK);

			xw.WriteStartElement("", "WindowHeight", URI_EXCEL_WORKBOOK);
			xw.WriteString("10020");
			xw.WriteEndElement();//WindowHeight

			xw.WriteStartElement("", "WindowWidth", URI_EXCEL_WORKBOOK);
			xw.WriteString("14955");
			xw.WriteEndElement();//WindowWidth

			xw.WriteStartElement("", "WindowTopX", URI_EXCEL_WORKBOOK);
			xw.WriteString("120");
			xw.WriteEndElement();//WindowTopX

			xw.WriteStartElement("", "WindowTopY", URI_EXCEL_WORKBOOK);
			xw.WriteString("15");
			xw.WriteEndElement();//WindowTopY

			xw.WriteStartElement("", "ProtectStructure", URI_EXCEL_WORKBOOK);
			xw.WriteString("False");
			xw.WriteEndElement();//ProtectStructure

			xw.WriteStartElement("", "ProtectWindows", URI_EXCEL_WORKBOOK);
			xw.WriteString("False");
			xw.WriteEndElement();//ProtectWindows

			xw.WriteEndElement();//ExcelWorkbook

			xw.WriteStartElement("", "Styles", URI_WORKBOOK);

			xw.WriteStartElement("", "Style", URI_WORKBOOK);
			xw.WriteAttributeString(NS_SS, "ID", URI_SS, "Default");
			xw.WriteAttributeString(NS_SS, "Name", URI_SS, "Normal");

			xw.WriteStartElement("", "Alignment", URI_WORKBOOK);
			xw.WriteAttributeString(NS_SS, "Vertical", URI_SS, "Center");
			xw.WriteEndElement();//Alignment

			xw.WriteStartElement("", "Borders", URI_WORKBOOK);
			xw.WriteEndElement();//Borders

			xw.WriteStartElement("", "Font", URI_WORKBOOK);
			xw.WriteAttributeString(NS_SS, "FontName", URI_SS, "宋体");
			xw.WriteAttributeString(NS_X, "CharSet", URI_X, "134");
			xw.WriteAttributeString(NS_SS, "Size", URI_SS, "12");
			xw.WriteEndElement();//Font

			xw.WriteStartElement("", "Interior", URI_WORKBOOK);
			xw.WriteEndElement();//Interior

			xw.WriteStartElement("", "NumberFormat", URI_WORKBOOK);
			xw.WriteEndElement();//NumberFormat

			xw.WriteStartElement("", "Protection", URI_WORKBOOK);
			xw.WriteEndElement();//Protection

			xw.WriteEndElement();//Style

			xw.WriteStartElement("", "Style", URI_WORKBOOK);
			xw.WriteAttributeString(NS_SS, "ID", URI_SS, "ColumnHeader");

			xw.WriteStartElement("", "Alignment", URI_WORKBOOK);
			xw.WriteAttributeString(NS_SS, "Horizontal", URI_SS, "Center");
			xw.WriteAttributeString(NS_SS, "Vertical", URI_SS, "Center");
			xw.WriteEndElement();//Alignment

			xw.WriteStartElement("", "Font", URI_WORKBOOK);
			xw.WriteAttributeString(NS_SS, "FontName", URI_SS, "宋体");
			xw.WriteAttributeString(NS_X, "CharSet", URI_X, "134");
			xw.WriteAttributeString(NS_SS, "Size", URI_SS, "12");
			xw.WriteAttributeString(NS_SS, "Bold", URI_SS, "1");
			xw.WriteEndElement();//Font

			xw.WriteEndElement();//Style

			#region Content Style

			xw.WriteStartElement("", "Style", URI_WORKBOOK);
			xw.WriteAttributeString(NS_SS, "ID", URI_SS, "String");

			xw.WriteStartElement("", "Alignment", URI_WORKBOOK);
			xw.WriteAttributeString(NS_SS, "Horizontal", URI_SS, "Left");
			xw.WriteAttributeString(NS_SS, "Vertical", URI_SS, "Center");
			xw.WriteEndElement();//Alignment

			xw.WriteStartElement("", "NumberFormat", URI_WORKBOOK);
			xw.WriteAttributeString(NS_SS, "Format", URI_SS, "@");
			xw.WriteEndElement();//NumberFormat

			xw.WriteEndElement();//Style

			xw.WriteStartElement("", "Style", URI_WORKBOOK);
			xw.WriteAttributeString(NS_SS, "ID", URI_SS, "Integer");

			xw.WriteStartElement("", "Alignment", URI_WORKBOOK);
			xw.WriteAttributeString(NS_SS, "Horizontal", URI_SS, "Right");
			xw.WriteAttributeString(NS_SS, "Vertical", URI_SS, "Center");
			xw.WriteEndElement();//Alignment

			xw.WriteStartElement("", "NumberFormat", URI_WORKBOOK);
			xw.WriteAttributeString(NS_SS, "Format", URI_SS, "0");
			xw.WriteEndElement();//NumberFormat

			xw.WriteEndElement();//Style

			xw.WriteStartElement("", "Style", URI_WORKBOOK);
			xw.WriteAttributeString(NS_SS, "ID", URI_SS, "Decimal");

			xw.WriteStartElement("", "Alignment", URI_WORKBOOK);
			xw.WriteAttributeString(NS_SS, "Horizontal", URI_SS, "Right");
			xw.WriteAttributeString(NS_SS, "Vertical", URI_SS, "Center");
			xw.WriteEndElement();//Alignment

			xw.WriteStartElement("", "NumberFormat", URI_WORKBOOK);
			xw.WriteAttributeString(NS_SS, "Format", URI_SS, "####0.00");
			xw.WriteEndElement();//NumberFormat

			xw.WriteEndElement();//Style

			xw.WriteStartElement("", "Style", URI_WORKBOOK);
			xw.WriteAttributeString(NS_SS, "ID", URI_SS, "DateTime");

			xw.WriteStartElement("", "Alignment", URI_WORKBOOK);
			xw.WriteAttributeString(NS_SS, "Horizontal", URI_SS, "Center");
			xw.WriteAttributeString(NS_SS, "Vertical", URI_SS, "Center");
			xw.WriteEndElement();//Alignment

			xw.WriteEndElement();//Style

			#endregion

			xw.WriteStartElement("", "Style", URI_WORKBOOK);
			xw.WriteAttributeString(NS_SS, "ID", URI_SS, "DocumentTitle");

			xw.WriteStartElement("", "Alignment", URI_WORKBOOK);
			xw.WriteAttributeString(NS_SS, "Horizontal", URI_SS, "Center");
			xw.WriteAttributeString(NS_SS, "Vertical", URI_SS, "Center");
			xw.WriteEndElement();//Alignment

			xw.WriteStartElement("", "Font", URI_WORKBOOK);
			xw.WriteAttributeString(NS_SS, "FontName", URI_SS, "宋体");
			xw.WriteAttributeString(NS_X, "CharSet", URI_X, "134");
			xw.WriteAttributeString(NS_SS, "Size", URI_SS, "24");
			xw.WriteAttributeString(NS_SS, "Bold", URI_SS, "1");
			xw.WriteEndElement();//Font

			xw.WriteEndElement();//Style

			xw.WriteStartElement("", "Style", URI_WORKBOOK);
			xw.WriteAttributeString(NS_SS, "ID", URI_SS, "SubTitle");

			xw.WriteStartElement("", "Alignment", URI_WORKBOOK);
			xw.WriteAttributeString(NS_SS, "Horizontal", URI_SS, "Right");
			xw.WriteAttributeString(NS_SS, "Vertical", URI_SS, "Center");
			xw.WriteEndElement();//Alignment

			xw.WriteEndElement();//Style

			xw.WriteEndElement();//Styles

			xw.Flush();

			do
			{
				if (!this.CanContinue())
				{
					xw.Close();
					return null;
				}
				iRowCount++;
				if (iRowCount > iSheetCount * SHEET_MAX_ROW)
				{
					if (iSheetCount > 0)
					{
						xw.WriteEndElement();//Table

						xw.WriteStartElement("", "WorksheetOptions", URI_WORKSHEET_OPTIONS);
						xw.WriteStartElement("", "ProtectObjects", URI_WORKSHEET_OPTIONS);
						xw.WriteString("False");
						xw.WriteEndElement();//ProtectObjects
						xw.WriteStartElement("", "ProtectScenarios", URI_WORKSHEET_OPTIONS);
						xw.WriteString("False");
						xw.WriteEndElement();//ProtectScenarios
						xw.WriteEndElement();//WorksheetOptions

						xw.WriteEndElement();//Worksheet
					}

					iSheetCount++;

					xw.WriteStartElement("", "Worksheet", URI_WORKBOOK);
					xw.WriteAttributeString(NS_SS, "Name", URI_SS, string.Format("第 {0} 页", iSheetCount));

					xw.WriteStartElement("", "Table", URI_WORKBOOK);
					//xw.WriteAttributeString(NS_SS, "ExpandedColumnCount", URI_SS, this.NamedColumnTitle.Count.ToString());
					//xw.WriteAttributeString(NS_SS, "ExpandedRowCount", URI_SS, SHEET_MAX_ROW.ToString());
					xw.WriteAttributeString(NS_X, "FullColumns", URI_X, "1");
					xw.WriteAttributeString(NS_X, "FullRows", URI_X, "1");
					//xw.WriteAttributeString(NS_SS, "DefaultColumnWidth", URI_SS, "54");
					xw.WriteAttributeString(NS_SS, "DefaultRowHeight", URI_SS, "14.25");

					for (i = 0; i < this.NamedColumnTitle.Count; i++)
					{
						xw.WriteStartElement("", "Column", URI_WORKBOOK);
						xw.WriteAttributeString(NS_SS, "AutoFitWidth", URI_SS, "1");
						xw.WriteEndElement();//Column
					}

					if (!string.IsNullOrEmpty(this._DocumentTitle))
					{
						xw.WriteStartElement("", "Row", URI_WORKBOOK);
						xw.WriteAttributeString(NS_SS, "Height", URI_SS, "31.5");

						i = this.NamedColumnTitle.Count - 1;
						xw.WriteStartElement("", "Cell", URI_WORKBOOK);
						xw.WriteAttributeString(NS_SS, "MergeAcross", URI_SS, i.ToString());
						xw.WriteAttributeString(NS_SS, "StyleID", URI_SS, "DocumentTitle");

						xw.WriteStartElement("", "Data", URI_WORKBOOK);
						xw.WriteAttributeString(NS_SS, "Type", URI_SS, "String");
						xw.WriteString(this._DocumentTitle);
						xw.WriteEndElement();//Data

						xw.WriteEndElement();//Cell

						xw.WriteEndElement();//Row

						xw.WriteStartElement("", "Row", URI_WORKBOOK);

						i = this.NamedColumnTitle.Count - 1;
						xw.WriteStartElement("", "Cell", URI_WORKBOOK);
						xw.WriteAttributeString(NS_SS, "MergeAcross", URI_SS, i.ToString());
						xw.WriteAttributeString(NS_SS, "StyleID", URI_SS, "SubTitle");

						xw.WriteStartElement("", "Data", URI_WORKBOOK);
						xw.WriteAttributeString(NS_SS, "Type", URI_SS, "String");
						xw.WriteString("日期：" + DateTime.Now.ToString("yyyy-M-d H:m:s"));
						xw.WriteEndElement();//Data

						xw.WriteEndElement();//Cell

						xw.WriteEndElement();//Row
					}

					xw.WriteStartElement("", "Row", URI_WORKBOOK);
					for (i = 0; i < this.NamedColumnTitle.Count; i++)
					{
						xw.WriteStartElement("", "Cell", URI_WORKBOOK);
						xw.WriteAttributeString(NS_SS, "StyleID", URI_SS, "ColumnHeader");

						xw.WriteStartElement("", "Data", URI_WORKBOOK);
						xw.WriteAttributeString(NS_SS, "Type", URI_SS, "String");
						xw.WriteString(this.NamedColumnTitle[i]);
						xw.WriteEndElement();//Data

						xw.WriteEndElement();//Cell
					}
					xw.WriteEndElement();//Row

					xw.Flush();

				}

				xw.WriteStartElement("", "Row", URI_WORKBOOK);
				for (i = 0; i < this.NamedColumnTitle.Count; i++)
				{
					xw.WriteStartElement("", "Cell", URI_WORKBOOK);
					xw.WriteAttributeString(NS_SS, "StyleID", URI_SS, "Default");

					o = this.GetData(iRowCount, i);
					xw.WriteStartElement("", "Data", URI_WORKBOOK);
					if (o != null && o.GetType() == typeof(string))
						xw.WriteAttributeString(NS_SS, "Type", URI_SS, "String");
					xw.WriteString(this.DataToString(iRowCount, i));
					xw.WriteEndElement();//Data

					xw.WriteEndElement();//Cell
				}
				xw.WriteEndElement();//Row

				xw.Flush();

			} while (this.HasData(iRowCount));

			if (iSheetCount > 0)
			{
				xw.WriteEndElement();//Table

				xw.WriteStartElement("", "WorksheetOptions", URI_WORKSHEET_OPTIONS);
				xw.WriteStartElement("", "ProtectObjects", URI_WORKSHEET_OPTIONS);
				xw.WriteString("False");
				xw.WriteEndElement();//ProtectObjects
				xw.WriteStartElement("", "ProtectScenarios", URI_WORKSHEET_OPTIONS);
				xw.WriteString("False");
				xw.WriteEndElement();//ProtectScenarios
				xw.WriteEndElement();//WorksheetOptions

				xw.WriteEndElement();//Worksheet
			}

			xw.WriteEndElement();//Workbook
			xw.WriteEndDocument();
			xw.Flush();

			xw.Close();

			return this._FileName;
		}

		#region IDisposable 成员

		/// <summary>
		/// 释放当前对象所有资源
		/// </summary>
		public void Dispose()
		{
			try
			{
				this.Dispose(true);
			}
			catch (Exception x)
			{
				Tracker.WriteError(x);
				Common.WriteEvent(x);
			}
		}

		/// <summary>
		/// 释放当前对象所有资源
		/// </summary>
		/// <param name="disposing">是否为手工释放</param>
		protected virtual void Dispose(bool disposing)
		{
			if (this._Disposed)
				return;

			#region var init

			this._OutStream = null;
			this._Processor = null;
			this._NamedColumnTitle = null;
			this._ColumnName = null;
			this._ColumnTitle = null;
			this._FileName = null;
			this._DocumentTitle = null;
			this._DataReader = null;
			this._DataTable = null;
			this._DataView = null;

			#endregion

			this._Disposed = true;
		}

		#endregion
	}


	/// <summary>
	/// 在CDataToExcel中用于数据处理器委托
	/// </summary>
	/// <param name="data">原数据</param>
	/// <returns>处理后数据</returns>
	public delegate object HDataProcessor(object data);
	//
}
//
